package com.ltmonitor.thread;

import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import com.ltmonitor.service.IQueryService;
import com.ltmonitor.web.util.SpringApplicationContextHolder;

import net.sf.jsqlparser.statement.select.Select;
import sun.applet.resources.MsgAppletViewer;

/**
 * 线程管理服务，用于对线程进行管理
 * @author Administrator
 */
public class ThreadManageService  extends BasicServiceThread{

	public ThreadManageService(String name, int sleepNum) {
		super(name, sleepNum);
		// TODO Auto-generated constructor stub
	}
	
	//线程队列
	private List<BasicServiceThread> threadList = new ArrayList<BasicServiceThread>();
	
	//查询服务对象
	private IQueryService queryService = null;
	
	//////////////////////////////////////////////////////////////////////////////////////////////////////方法
	
	//循环执行前的初始化
	protected String  threadServiceInit() {
		String msg = "";
		if(queryService == null) {
			queryService = SpringApplicationContextHolder.getBean("queryService");
			if(queryService == null) {
				msg += "查询服务对象创建失败！";
			}
		}
		return msg;
	}
	
	//服务运行
	protected void threadServiceRun() {
//		outInfo("线程管理器执行中.........");

		// 校验线程开关状态
		checkThreadSwitch();

		if (ifCheck()) {
			ManageThreads();
		}
	}
	

	
	
	
////////////////////////////////////////////////////////////////////////////开关线程相关代码  start
	
	
	//从配置文件中读取线程开关，然后根据开关的值进行添加和删除
	public void checkThreadSwitch() {
//		threadLog.info("开始校验线程开关数据.....");
		if(queryService != null) {
			String queryId = "servcieThread.selectAllDatas";
			Map map = new HashMap();
			List<Map<String, Object>> list = queryService.query(queryId, map);
			if(list.size() > 0) {
				for(int i=0 ; i<list.size() ; i++) {
					String threadName =  list.get(i).get("name").toString();
					String switchValue = list.get(i).get("switch").toString();
					//开始
					if(switchValue.equals("1")) {
						//线程需要打开
						int index = getObjFromList(threadName);
						if(index  <= -1) {
							//数据不存在，新建
							addOneThread(createOneNewThread(list.get(i)));
						}
					}else {
						//线程需要关闭
						int index = getObjFromList(threadName);
						if(index > -1) {
							//数据存在，停止并关闭
							BasicServiceThread temp = threadList.get(index);
							if(temp != null) {
								if(temp.ifRun()) {//先停止，等待下次停止后注销
									temp.stopRun();								
								}else {
									//线程停止，清除
									threadLog.info("当前线程队列数量为：" + threadList.size() + "  ， 开始从队列中移除第" + (index +1) + "个线程对象："  + threadName + ".......");
									threadList.remove(index);
									threadLog.info("移除成功!当前线程队列数量为：" + threadList.size());
								}
							}
						}
					}
				}
			}
			
		}
	}
	
	//根据名称，从链表中查找当前名称的线程索引
	private int getObjFromList(String name) {
		int index = -1;
		for(int i=0 ; i< threadList.size(); i++) {
			if(name.equals(threadList.get(i).name)) {
				index = i;
				break;
			}
		}
		return index;
	}
	
	//根据信息获取一个线程数据
	private BasicServiceThread createOneNewThread(Map map) {
		BasicServiceThread result = null;
		try {
			int sleepNum = 0;
			if(map.containsKey("sleepNum")) {
				sleepNum = Integer.valueOf(map.get("sleepNum").toString());
			}
			if(sleepNum <= 0 ) {
				sleepNum = 1000 * 3;
			}
			
			int sleepCount = 0;
			if(map.containsKey("sleepCount")) {
				sleepCount = Integer.valueOf(map.get("sleepCount").toString());
			}
			if(sleepCount <= 0 ) {
				sleepCount = 1;
			}
			
			threadLog.info("开始添加一个线程，线程类名称：" + map.get("className").toString() + " ， 线程名称：" + map.get("name").toString()  
					+ "  , sleepNum=" +sleepNum+ " , sleepCount = " + sleepCount);
			Constructor constructor = Class.forName(map.get("className").toString()).getDeclaredConstructor(new Class[] {String.class,int.class});
			 result = (BasicServiceThread) constructor.newInstance(new Object[] {map.get("name").toString() ,sleepNum});
			 
			 result.sleepCount = sleepCount;
			 if(map.containsKey("value1")) {
				 result.value1 = map.get("value1").toString();
			 }
			 
			 if(map.containsKey("value2")) {
				 result.value2 = map.get("value2").toString();
			 }
			 
		} catch (Exception e) {
			// TODO: handle exception
			threadLog.error("根据配置文件创建新的服务线程失败，线程名称：" + name + "  ， 失败信息：" + e.getMessage());
		}
//		Class.forName(serviceName).getClass();
		return result;
	}
	
	
	
	////////////////////////////////////////////////////////////////////////////开关线程相关代码  end
	
	
	
	/**
	 * 是否可以进行线程校验，目前两点至两点31，不进行状态校验
	 * @return
	 */
	private boolean ifCheck() {
		boolean returnFlg = true; // 默认允许校验
		
		//两点到两点31分不允许校验
		Calendar time = Calendar.getInstance();
		int hour = time.get(Calendar.HOUR_OF_DAY);
		int min = time.get(Calendar.MINUTE);
		int second = time.get(Calendar.SECOND);
		if(hour == 2 && min >=0 && min <= 31 ) {
			returnFlg = false;
			if(second < 5) {
				outInfo("当前时间不校验线程状态！");
			}
		}
		//返回结果
		return returnFlg;
	}
	
	/**
	 * 管理线程，检查线程是否正常活动，如果不活动则进行处理
	 * @return
	 */
	private void ManageThreads() {
		try {
			if(threadList.size() > 0) {
				for(int i=0 ; i<threadList.size() ; i++) {
					BasicServiceThread temp = threadList.get(i);
					//检查线程状态,如果异常，则重建新的线程
					if(temp != null) {
						if(!temp.checkState()) {
							BasicServiceThread newTemp = getOneNewThread(temp);
							try {
								temp.stopRun();//停止执行
								temp.interrupt();//设置阻塞异常，停止执行								
								if(newTemp != null) {
									newTemp.start();
									outInfo("当前列表中的数量：" + threadList.size());
									threadList.add((i+1), newTemp);
									outInfo("添加新对象后列表中的数量：" + threadList.size());
									threadList.remove(temp);
									outInfo("移除旧对象后列表中的数量：" + threadList.size());
								}else {
									outError("创建新的线程：" + temp.name + "失败！！！！");
								}
							} catch (Exception e) {
								// TODO: handle exception
								outError("停止旧线程并创建新线程 " + temp.name + " 错误：" + e.getMessage());
							}
						}						
					}else {
						outError("线程列表中，第 " + (i+1) + " 个线程对象为null，出现异常状态！++++++++++++++++++++++");
					}
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			String msg = "线程管理异常：" + e.getMessage();
			threadLog.error(msg);
		}
	}
	
	
	
	//根据原对象的信息，获取一个新的线程对象
	private BasicServiceThread getOneNewThread(BasicServiceThread thread) {
		BasicServiceThread temp = null;
		try {
			Constructor constructor =  thread.getClass().getDeclaredConstructor(new Class[] {String.class,int.class});
			constructor.setAccessible(true);
			temp =  (BasicServiceThread) constructor.newInstance(new Object[] {thread.name,thread.sleepNum});
		} catch (Exception e) {
			// TODO: handle exception
			String msg = name + "获取新线程对象失败：" + e.getMessage();
			threadLog.error(msg);
		}
		return temp;
	}
	
	/**
	 * 添加一个线程服务
	 * @param thread
	 */
	public void addOneThread(BasicServiceThread thread) {
		String msg = "";
		if(thread != null) {
			thread.start();
			threadList.add(thread);
			msg +=thread.name + "线程添加成功!";	
		}else {
			msg += "需要添加的线程对象为空，无法添加！";
		}
		outInfo(msg);
	}
	
	
	/**
	 * 停止所有的线程
	 * @return
	 */
	public String stopAll() {
		String msg = "";
		if(threadList.size() > 0) {
			for(int i=0 ; i<threadList.size() ; i++) {
				BasicServiceThread temp = threadList.get(i);
				temp.stopRun();
			}
		}
		return msg;
	}
	
}
